package com.cgnpc.scp.sri.laboratory.service.impl;

import cn.com.cgnpc.aep.bizcenter.appcenter.sdk.result.ApiResult;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cgnpc.cud.core.domain.AjaxResult;
import com.cgnpc.cuddemo.utils.IDHelper;
import com.cgnpc.framework.service.IBpmCenterService;
import com.cgnpc.framework.userinfo.CurrentUser;
import com.cgnpc.scp.common.bean.CreateFileInfo;
import com.cgnpc.scp.common.bean.MyPageResult;
import com.cgnpc.scp.common.exception.ScpException;
import com.cgnpc.scp.common.pojo.UserInfo;
import com.cgnpc.scp.common.service.AppConstantService;
import com.cgnpc.scp.common.utils.MyPageResultUtil;
import com.cgnpc.scp.common.utils.StringUtil;
import com.cgnpc.scp.run.utils.CommonExportUtil;
import com.cgnpc.scp.sri.laboratory.mybatis.entity.*;
import com.cgnpc.scp.sri.laboratory.mybatis.mapper.client.LaboratoryAnnualPlanMapper;
import com.cgnpc.scp.sri.laboratory.mybatis.mapper.client.LaboratoryAnnualPlanPhaseMapper;
import com.cgnpc.scp.sri.laboratory.mybatis.mapper.client.LaboratoryAnnualPlanPhasePersonMapper;
import com.cgnpc.scp.sri.laboratory.pojo.LaboratoryAnnualPlanVo;
import com.cgnpc.scp.sri.laboratory.service.LaboratoryAnnualPlanService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.*;

@Service("laboratoryAnnualPlanService")
public class LaboratoryAnnualPlanServiceImpl implements LaboratoryAnnualPlanService {
    private static final Logger LOGGER = LoggerFactory.getLogger(LaboratoryAnnualPlanServiceImpl.class);

    @Autowired
    private LaboratoryAnnualPlanMapper laboratoryAnnualPlanMapper;

    @Autowired
    private LaboratoryAnnualPlanPhaseMapper laboratoryAnnualPlanPhaseMapper;

    @Autowired
    private LaboratoryAnnualPlanPhasePersonMapper laboratoryAnnualPlanPhasePersonMapper;

    @Autowired
    private AppConstantService appConstantService;

    @Autowired
    private SqlSession sqlSession;

    @Autowired
    IBpmCenterService bpmCenterService;

    @Autowired
    private CurrentUser currentUser;

    @Override
    public MyPageResult<LaboratoryAnnualPlan> queryListPage(Map<String, Object> params) {
        MyPageResult<LaboratoryAnnualPlan> re = null;
        int pageNum = 1;
        int pageSize = 10;
        try {
            pageNum = Integer.parseInt(params.get("pageNum") + "");
            pageSize = Integer.parseInt(params.get("pageSize") + "");
        }catch (Exception e){
            e.printStackTrace();
        }
        Page<LaboratoryAnnualPlan> queryPage = PageHelper.startPage(pageNum, pageSize);
        laboratoryAnnualPlanMapper.listPage(params);
        PageInfo<LaboratoryAnnualPlan> pageResult = new PageInfo<>(queryPage.getResult());
        re = MyPageResultUtil.createMyPageResult(pageResult);

        return re;
    }

    @Override
    public LaboratoryAnnualPlanVo planInfo(String id) {
        List<LaboratoryAnnualPlanPhase> planList = laboratoryAnnualPlanPhaseMapper.selectList(new QueryWrapper<LaboratoryAnnualPlanPhase>()
                .select("*"
                        ,"(select file_center_file_name from tbl_common_fileupload tcf where tcf.file_center_file_id = tbl_sri_laboratory_annualplanphase.file_id) as file_name"
                        ,"(select file_center_url from tbl_common_fileupload tcf where tcf.file_center_file_id = tbl_sri_laboratory_annualplanphase.file_id) as file_path"
                )
                .eq("annual_plan_id",id));
        if(planList != null && planList.size() != 0){
            for(LaboratoryAnnualPlanPhase phase : planList){
                List<LaboratoryAnnualPlanPhasePerson> persons = laboratoryAnnualPlanPhaseMapper.getPersonByPhaseId(phase.getId());
                phase.setPersons(persons);
            }
        }

        LaboratoryAnnualPlan info = laboratoryAnnualPlanMapper.planInfo(id);

        LaboratoryAnnualPlanVo vo = new LaboratoryAnnualPlanVo();
        vo.setLaboratoryAnnualPlan(info);
        vo.setLaboratoryAnnualPlanPhases(planList);
        return vo;
    }

    @Override
    public CreateFileInfo exportExcel(Map<String, Object> params) throws Exception {
        CreateFileInfo createFileInfo;

        try {
            List<String> titleList = Arrays.asList(
                    "计划名称","实验室","年度"
                    ,"计划开始日期","计划完成日期","计划提交人","计划提交日期","审批完成日期","状态"
            );
            List<String> fields = Arrays.asList("planName","laboratoryName", "year"
                    ,"planStartTime","planEndTime","createUserName","createTime","processFinalTime","sriStatus"
            );

            CommonExportUtil<LaboratoryAnnualPlan> util = new CommonExportUtil<>();
            createFileInfo = util.exportExcel(appConstantService, sqlSession, titleList, fields
                    , "com.cgnpc.scp.sri.laboratory.mybatis.mapper.client.LaboratoryAnnualPlanMapper"
                    ,"listPageExport", params);
        } catch (Exception e) {
            throw e;
        }

        return createFileInfo;
    }

    @Override
    public List<String> getAllYear() {
        return laboratoryAnnualPlanMapper.getAllYear();
    }

    @Override
    public List<LaboratoryAnnualPlan> getAllPlanInfo() {
        return laboratoryAnnualPlanMapper.selectList(new QueryWrapper<LaboratoryAnnualPlan>()
        .select("*","concat(laboratory_name,'-', year) as plan_name")
        .eq("process_status","1")
        .eq("operate_type","1"));
    }

    @Transactional
    @Override
    public synchronized AjaxResult planSave(Map<String, Object> params) throws Exception {
        Map<String, Object> win = (Map<String, Object>)params.remove("laboratory");
        win.remove("createTime");
        win.remove("lastUpdateTime");
        if(!StringUtil.isNullOrSpace(win.get("id")+"") && !"1".equals(params.get("isModifyDraft"))){
            String planId = win.remove("id")+"";
            win.put("infoId", planId);
        }
        LaboratoryAnnualPlan info = new LaboratoryAnnualPlan();
        BeanUtils.populate(info, win);
        info = saveOrUpdateInfo(info);
        List<Map<String, Object>> phaseMapList = (List<Map<String, Object>>) params.get("phases");
        List<LaboratoryAnnualPlanPhase> phases = new ArrayList<>();
        for(Map<String, Object> map : phaseMapList){
            LaboratoryAnnualPlanPhase phase = new LaboratoryAnnualPlanPhase();
            String phaseId = IDHelper.uuid();
            phase.setId(phaseId);
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String plannedStartTime = map.remove("plannedStartTime").toString();
            String plannedEndTime = map.remove("plannedEndTime").toString();
            map.remove("createTime");
            map.remove("lastUpdateTime");
            map.remove("startTime");
            map.remove("endTime");
            List<Map<String, Object>> phasePersons = (List<Map<String, Object>>)map.remove("persons");
            laboratoryAnnualPlanPhasePersonMapper.delete(new QueryWrapper<LaboratoryAnnualPlanPhasePerson>()
            .eq("annual_plan_phase_id",phaseId));
            for(Map<String, Object> personMap : phasePersons){
                //System.out.println("personMap-->>"+personMap);
//                map.remove("createTime");
                LaboratoryAnnualPlanPhasePerson person = new LaboratoryAnnualPlanPhasePerson();
//                BeanUtils.populate(person, personMap);
                person.setId(IDHelper.uuid());
                person.setAnnualPlanPhaseId(phaseId);
                person.setCreateTime(new Date());
                person.setPeopleName(personMap.get("peopleName").toString());
                person.setPeopleNumber(personMap.get("peopleNumber").toString());
                laboratoryAnnualPlanPhasePersonMapper.insert(person);
            }
            //System.out.println("map-->>"+map);
            BeanUtils.populate(phase, map);
            phase.setPlannedStartTime(sdf.parse(plannedStartTime));
            phase.setPlannedEndTime(sdf.parse(plannedEndTime));
            phases.add(phase);
        }
        saveOrUpdatePlanPhase(phases, info.getId());

        params.put("next_deal_name", JSONArray.parseArray(JSON.toJSONString(params.remove("next_deal_name"))));
        params.put("win", JSON.parseObject(JSON.toJSONString(win)));
        params.put("folio", info.getFolio());
        ApiResult apiResult = null;
        //判断是否为保存草稿
        params.put("appFormId", info.getId());
        if("1".equals(params.get("isSaveDraft"))){
            if(!"1".equals(params.get("isModifyDraft")+"")){
                bpmCenterService.addDraft(params);
            }
        }else{
            LOGGER.info("流程启动---");
            apiResult = bpmCenterService.startProcess(params);
            LOGGER.info("result--{}" , apiResult);
        }
        return AjaxResult.success().put("data", info);
    }

    private LaboratoryAnnualPlan saveOrUpdateInfo(LaboratoryAnnualPlan laboratoryAnnualPlan) {

        Date date = new Date();
        UserInfo currentUserDetail = currentUser.getCurrentUserDetail();
        laboratoryAnnualPlan.setLastUpdateTime(date);
        laboratoryAnnualPlan.setLastUpdateUser(currentUserDetail.getUserId());
        laboratoryAnnualPlan.setLastUpdateUserName(currentUserDetail.getUserName());
        if(StringUtil.isNullOrSpace(laboratoryAnnualPlan.getId())){
            //新增
            laboratoryAnnualPlan.setId(IDHelper.uuid());
            laboratoryAnnualPlan.setCreateTime(date);
            laboratoryAnnualPlan.setCreateUser(currentUserDetail.getUserId());
            laboratoryAnnualPlan.setCreateUserName(currentUserDetail.getUserName());
            String folio = laboratoryAnnualPlan.getProcessName() + "-" + laboratoryAnnualPlan.getCreateUser() + "-" +
                    new SimpleDateFormat("yyyyMMdd").format(laboratoryAnnualPlan.getCreateTime());
            laboratoryAnnualPlan.setFolio(folio);
            laboratoryAnnualPlan.setProcessStatus("0");
            laboratoryAnnualPlan.setStatus("1");
            laboratoryAnnualPlan.setPlanStatus(1);
            laboratoryAnnualPlanMapper.insert(laboratoryAnnualPlan);
        }else{
            //更新
            laboratoryAnnualPlanMapper.updateById(laboratoryAnnualPlan);
        }
        return laboratoryAnnualPlan;
    }

    /**********************************
     * 用途说明: 审批操作（通过或驳回）
     * 参数说明 params
     * 返回值说明:
     ***********************************/
    @Override
    @Transactional
    public ApiResult submitProcess(Map<String, Object> params) throws Exception {
        // 流程除了启动环节，任意环节提交时均要保存流程实例id
        String procInstId = params.get("procInstId").toString();
        if (StringUtil.isNullOrSpace(procInstId)) {
            throw new ScpException("procInstId is missing.");
        }
        //判断是前进还是后退
        String flag = params.get("deal_answer").toString();
        ApiResult apiResult = null;
        // 根据环节名称判断当前处理逻辑
        String act_name = params.get("now_deal_act").toString();
        String formInstID = params.get("formInstID").toString();
        params.put("next_deal_name",JSONArray.parseArray(JSON.toJSONString(params.remove("next_deal_name"))));
        Object copygive = params.remove("copygive");
        if(copygive != null && !"".equals(copygive)){
            params.put("copygive",JSONArray.parseArray(JSON.toJSONString(copygive)));
        }
        if (!StringUtil.isNullOrSpace(act_name)
                && ("020".equals(act_name) || "030".equals(act_name) ||"010".equals(act_name))
        ) {
            if ("1".equals(flag)) {
                //提交
                if("true".equals(params.get("isEnd").toString())){
                    //提交且为最后一步 （此时需要将计划显示，若操作类型为变更，需要把计划变更信息覆盖到原计划）
//                Integer operateType = Integer.parseInt(params.get("operateType")+"");
                    LaboratoryAnnualPlan getOperateTypeInfo = laboratoryAnnualPlanMapper.selectOne(new QueryWrapper<LaboratoryAnnualPlan>()
                            .select("*","concat(laboratory_name,'-', year) as plan_name")
                            .eq("id",formInstID));
                    String operateType = getOperateTypeInfo.getOperateType();
                    //操作类型,1:计划新增，2:计划信息变更
                    if("1".equals(operateType)){
                        LaboratoryAnnualPlan info = new LaboratoryAnnualPlan();
                        info.setProcInstId(procInstId);
                        info.setProcessStatus("1");
                        info.setId(formInstID);
                        info.setProcessFinalTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
                        laboratoryAnnualPlanMapper.updateById(info);
                    }else if("2".equals(operateType)){
                        //拿到更新的那条数据
                        LaboratoryAnnualPlan info = getOperateTypeInfo;
                        //把id改了，更新那条新增的计划
                        info.setId(info.getInfoId());
                        info.setOperateType("2");
                        info.setProcInstId(procInstId);
                        info.setProcessStatus("1");
                        info.setProcessFinalTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
                        laboratoryAnnualPlanMapper.updateById(info);
                    }else if("3".equals(operateType)){
                        //若操作类型为关闭，需要更新其状态
                        LaboratoryAnnualPlan info = new LaboratoryAnnualPlan();
                        info.setId(formInstID);
                        info.setStatus("0");
                        info.setProcessFinalTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
                        laboratoryAnnualPlanMapper.updateById(info);
                    }
                }
                apiResult = bpmCenterService.submitworklistitem(params);
//                processAudit(params);
            } else if ("2".equals(flag)) {
                //驳回
                apiResult = bpmCenterService.rollBackAction(params);
            }
        } else {
            throw new ScpException("activity not found.");
        }
        return apiResult;
    }

    private void saveOrUpdatePlanPhase(List<LaboratoryAnnualPlanPhase> phaseList, String infoId){
        if(phaseList == null || phaseList.size() == 0){
            return;
        }
        laboratoryAnnualPlanPhaseMapper.deleteByInfoId(infoId);
        UserInfo currentUserDetail = currentUser.getCurrentUserDetail();
        for(LaboratoryAnnualPlanPhase phase : phaseList){
            //phase.setId(IDHelper.uuid());
            phase.setAnnualPlanId(infoId);
            phase.setPlanStatus(1);
            Date date = new Date();
            phase.setCreateTime(date);
            phase.setCreateUser(currentUserDetail.getUserId());
            phase.setCreateUserName(currentUserDetail.getUserName());
            phase.setLastUpdateTime(date);
            phase.setLastUpdateUser(currentUserDetail.getUserId());
            phase.setLastUpdateUserName(currentUserDetail.getUserName());
            laboratoryAnnualPlanPhaseMapper.insert(phase);
        }
    }

    @Override
    public ApiResult deleteDraft(Map<String, Object> params) throws Exception {
        String infoId = params.get("formno").toString();
        laboratoryAnnualPlanPhaseMapper.deleteByInfoId(infoId);
        laboratoryAnnualPlanMapper.deleteById(infoId);

        return bpmCenterService.deleteMyDraft(params);
    }

}
